package com.amiu.shiro;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.amiu.service.PermissionService;
import com.amiu.service.RoleService;
import com.amiu.shiro.db.permission.Permission;
import com.amiu.shiro.db.role.Role;
import com.amiu.shiro.db.user.User;
import com.amiu.shiro.db.user.UserDao;
import com.amiu.shiro.db.user_role.UserRole;
import com.amiu.shiro.db.user_role.UserRoleDao;
import com.amiu.util.MapUtil;

public class MyRealm extends AuthorizingRealm {
	@Autowired
	RoleService roleService;
	@Autowired
	PermissionService permissionService;
	@Autowired
	UserDao userDao;
	@Autowired
	UserRoleDao userRoleDao;
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		// 获取当前登录对象
		User user = (User) principals.getPrimaryPrincipal();
		// 查询拥有角色
		Map<Long, Role> mapRole = roleService.findRoleByUserId(user.getId());

		List<Long> roleIds = MapUtil.toListKey(mapRole);
		// 查询角色拥有的权限
		Map<Long, Permission> mapPermission = permissionService
				.findByRoleId(roleIds);

		Set<String> roles = null;
		Set<String> stringPermissions = null;
		try {
			// 将需要的字段转换为Set格式，name是实体类Role的字段
			roles = MapUtil.toSet(mapRole, "name");
			stringPermissions = MapUtil.toSet(mapPermission, "name");
		} catch (Exception e) {
			// 这里是MapUtil工具类捕捉的异常
			e.printStackTrace();
		}
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		// 将角色与权限放入SimpleAuthorizationInfo对象
		authorizationInfo.setRoles(roles);
		authorizationInfo.setStringPermissions(stringPermissions);
		// 返回给shiro
		return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {

		UsernamePasswordToken userToken = (UsernamePasswordToken) token;

		String username = userToken.getUsername();
		// String password = new String((char[]) userToken.getCredentials());

		User user = userDao.findByName(username);

		if (user == null) {
			throw new UnknownAccountException();
		}
		if (user.isIs_lock()) {
			// 账户被锁定
			throw new LockedAccountException();
		}

		// 从数据库中取出盐
		String salt = user.getPassword_salt();
		String password = user.getPassword();
		// 转换为byte类型的盐
		ByteSource byteSalt = ByteSource.Util.bytes(salt);
		
		//简单验证,直接验证，不加盐的
//		SimpleAuthenticationInfo info = 
//				new SimpleAuthenticationInfo(user,password, getName());
		
		//加盐验证
		 SimpleAuthenticationInfo info =
				 new SimpleAuthenticationInfo(
						 user,password, byteSalt, getName());

		return info;
	}
	
//	@Override
//	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
//		/**
//		 * 设置我们的自己的[用户匹配器]
//		 * 功能1：可以匹配加密的密码
//		 * 功能2：可以设置登陆次数，短时间内超过次数则锁定，设置时间内无法登陆
//		 */
//		RetryLimitHashedCredentials loginRetryLimitMatcher = 
//				new RetryLimitHashedCredentials(cacheManager);
//		
//		super.setCredentialsMatcher(loginRetryLimitMatcher);
//	}
	
}
